/* $RCSFile: Monitoring.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/ADNCRM.Core/Security/Monitoring.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:29  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Globalization;

using AddonNice.Core;
using AddonNice.Configuration;
using AddonNice.Diagnostics;
using AddonNice.Settings;

namespace AddonNice.Security
{

    public enum MonLogType : int { UnKnown = -1, PageRequest = 0, Login, Logon, Logoff, PageView, ItemView, ItemDetail, CrmItemView, CrmItemDetail, LogExt = 100, }
    
    // CS 24/10/04 define a custom event class 
	public class MonitorEventArgs : EventArgs
    {
        #region local data
        
        protected MonLogType _LogType               =   MonLogType.UnKnown;
        // current Crm User Ids
        protected int				_typeCode		=	-1;
		protected Guid			    _CrmUserID		=	Guid.Empty;
		// current user, internal id only when Forms authentication
        protected Guid			    _UserId		    =	Guid.Empty;
		// current username
        protected string			_UserName		=	string.Empty;
		// Portal
        protected int				_PortalID		=	0;
		// Page
        protected int		        _PageID			=	0;
		// Page
        protected int			    _ModuleID		=	0;
		// Normally Page Item, else when CRM Item is not empty typecode of CRM Item
        protected int			    _ItemID			=	0;
		// Crm Item 
        protected Guid		        _CrmItemID		=	Guid.Empty;
		// action type
        protected string			_actionType		=	string.Empty;
		// free comment field
        protected string			_userField		=	string.Empty;

        protected bool              _isUnderCRM     =   false;
        protected bool              _isCallBack     =   false;
        
        #endregion local data
        
        public MonLogType LogType 
		{
			get
			{
				return _LogType;
			}
		}

		/// <summary>
		/// Current user, internal id only when Forms authentication, else Guid.Empty
		/// </summary>
        public Guid UserId
		{
			get
			{
				return _UserId;
			}
		}

        public string UserName
		{
			get
			{
				return _UserName;
			}
		}


        /// <summary>
        /// current Crm User typecode: systemUser, Account, contact or Prospect
        /// </summary>
        public int	typeCode
		{
			get
			{
				return _typeCode;
			}
		}

        /// <summary>
        /// current Crm User Id
        /// </summary>
        public Guid CrmUserID
		{
			get
			{
				return _CrmUserID;
			}
		}
		
        public int PortalID
		{
			get
			{
				return _PortalID;
			}
		}

		public int	PageID
		{
			get
			{
				return _PageID;
			}
		}

		public int	ModuleID
		{
			get
			{
				return _ModuleID;
			}
		}

		/// <summary>
		/// Normally Page Item, else when CRM Item is not empty typecode of CRM Item
		/// </summary>
		public int	ItemID
		{
			get
			{
				return _ItemID;
			}
		}

		/// <summary>
		/// CRM Item its typecode is in ItemID
		/// </summary>
        public Guid CrmItemId
		{
			get
			{
				return _CrmItemID;
			}
		}
        /// <summary>
        /// Old LogType
        /// </summary>
        public string actionType		
		{
			get
			{
				return _actionType;
			}
		}
		
        public string userField				
		{
			get
			{
				return _userField;
			}
		}
        
        public bool isUnderCRM
        {
            get
            {
                return _isUnderCRM;
            }
        }

        public bool isCallBack
        {
            get
            {
                return _isCallBack;
            }
        }

        public MonitorEventArgs(MonLogType ltp,Guid FormsUserID,string userName,int CrmUserTpCode,Guid CRMUserID,int PID,int TbID,string action, string uField,bool underCRM,bool CallBack)
		{
            if ( MonitoringTrace.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]MonitorEventArgs Ctor FormsUserID: {0}, CRMUserID: {1}, PID: {2}, pgID: {3}, action: {4}, uField: {5}, underCRM: {6}", 
                    new object[]{FormsUserID,CRMUserID,PID,TbID,action, uField,underCRM}),MonitoringTrace.Sw.Info);
            _LogType        =   ltp;
			_UserId		    =	FormsUserID;
            _UserName       =   userName;
            _typeCode       =   CrmUserTpCode;
			_CrmUserID		=	CRMUserID;
			_PortalID		=	PID;
			_PageID			=	TbID;
			_actionType		=	action;
			_userField		=	uField;
            _isUnderCRM     =   underCRM;
            _isCallBack     =   CallBack;
		}

        public MonitorEventArgs(MonLogType ltp,Guid UID,string userName,int tpCode,Guid CRMUID,int PID,int pgID,int mdID,int itmID,Guid CrmItmID,string action, string uField,bool underCRM,bool CallBack)
		{
            if ( MonitoringTrace.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]MonitorEventArgs Ctor UID: {0}, CRMID: {1}, PID: {2}, pgID: {3}, action: {4}, uField: {5}, , underCRM: {6})", 
                    new object[]{UID,CRMUID,PID,pgID,action, uField,underCRM}),MonitoringTrace.Sw.Info);
            _LogType        =   ltp;
			_UserId		    =	UID;
            _UserName       =   userName;
            _typeCode       =   tpCode;
			_CrmUserID		=	CRMUID;
			_PortalID		=	PID;
			_PageID			=	pgID;
			_ModuleID		=	mdID;
			_ItemID		    =	itmID;
			_CrmItemID		=	CrmItmID;
			_actionType		=	action;
			_userField		=	uField;
            _isUnderCRM     =   underCRM;
            _isCallBack     =   CallBack;
		}
        
        public override string ToString()
        {
            return string.Format(
                "MonitorEventArgs object UserId: {0}, typeCode: {1}, CrmUserID: {2}, PortalID: {3}, PageID: {4}, ModuleID: {5}, ItemID: {6}, CrmItemID: {7}, actionType: {8}, userField: {9}, underCRM: {10}", 
                new object[]{_UserId,_typeCode,_CrmUserID,_PortalID,_PageID,_ModuleID,_ItemID,_CrmItemID,_actionType,_userField,_isUnderCRM});
        }
	}

	/// <summary>
	/// Monitoring class is instantiated By InitApp, only one object exists
	/// It is used to maintain and show site statistics such as who has logged on and at what time.
	/// </summary>
	public class Monitoring
	{
		MonitoringDB MonitorDB	=	new MonitoringDB();
		public Monitoring()
		{
            if ( MonitoringTrace.Sw.TraceVerbose )
                Trace.WriteLine( "[V]Monitoring Ctor.",MonitoringTrace.Sw.Info);
			// Monitor every login 
			PortalSecurity.LoginEvent		+=	new LoginEventHandler(MonitorLogin);
		}

		/// <summary>
		/// Handler specialized for login events
		/// </summary>
		public void MonitorLogin(LoginEventArgs e)
		{
			try
			{
                if ( MonitoringTrace.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]Monitoring LogEntry LoginEventArg: [{0}]", e),MonitoringTrace.Sw.Info);
                int PortalID    =   e.portalSettings.PortalID;
                int PageID      =   ( e.portalSettings.ActivePageSettings != null ) ? e.portalSettings.ActivePageSettings.PageID:-1;
                int ModuleID    =   0;
                bool isUnderCRM =   PortalSettings.IsUnderCRM;
                switch ( e.IsLogin )
                {
                    case LogType.Logon:
                    MonitorDB.LogEntry(MonLogType.Logon,e.User.ProviderUserKey,e.User.Name,e.User.typeCode,e.User.CrmId,PortalID,PageID,ModuleID,0,Guid.Empty,"Logon",string.Empty,isUnderCRM,e.IsCallBack);
                    break;
                    case LogType.Logoff:
                    MonitorDB.LogEntry(MonLogType.Logoff,e.User.ProviderUserKey,e.User.Name,e.User.typeCode,e.User.CrmId,e.portalSettings.PortalID,PageID,ModuleID,0,Guid.Empty,"Logoff",string.Empty,isUnderCRM,e.IsCallBack);
                    break;
                    case LogType.Login:
                    MonitorDB.LogEntry(MonLogType.Login,e.User.ProviderUserKey,e.User.Name,e.User.typeCode,e.User.CrmId,e.portalSettings.PortalID,PageID,ModuleID,0,Guid.Empty,"Login",string.Empty,isUnderCRM,e.IsCallBack);
                    break;
                }
			}
			catch (Exception ex)
			{
				if ( SecurityTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]Monitoring MonitorLogin portalID: {0}, ex :{1}",e.portalSettings.PortalID,ex),SecurityTraceSwitch.Sw.Info);
			}
		}

		/// <summary>
		/// Handler used by Page_Load in DefaultModulesPage.aspx
		/// </summary>
		public void LogEntry(MonitorEventArgs e)
		{
			try
			{
                if ( MonitoringTrace.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]Monitoring MonitorLogin LoginEventArg: [{0}]", e),MonitoringTrace.Sw.Info);
				MonitorDB.LogEntry(e.LogType,e.UserId,e.UserName,e.typeCode,e.CrmUserID,e.PortalID,e.PageID,e.ModuleID,e.ItemID,e.CrmItemId,e.actionType,e.userField,e.isUnderCRM,e.isCallBack);
			}
			catch (Exception ex)
			{
				if ( SecurityTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]Monitoring LogEntry ex : {0}",ex),SecurityTraceSwitch.Sw.Info);
			}
		}
	}
}
